/*************************************************************************
	> File Name: jsonbuffer.cpp
	> Author: xuwenlong
	> Mail: myxuan475@126.com 
	> Created Time: 2018年01月23日 星期二 16时38分33秒
 ************************************************************************/

#include <stdio.h>
#include <json/reader.h>
#include <logger.h>
#include "jsonbuffer.h"
#include <utils/decrypt.h>
#include <arpa/inet.h>

using namespace std;

JsonBuffer::JsonBuffer() {
    m_iStartPos = 0;
}

bool JsonBuffer::getJsonFromBuffer(Json::Value &output)
{
    AutoLock auto_lock(m_bufferLock);
    if (m_szBuffer.empty())
        return false;

    string jsonBuffer;
    if (!parseJson(jsonBuffer))
        return false;
    std::string errs;

    Json::CharReaderBuilder builder;
    builder["collectComments"] = false;
    Json::CharReader *reader = builder.newCharReader();

    const char *pStr = jsonBuffer.c_str();
    int   length = jsonBuffer.length();
    if (reader->parse(pStr,pStr+length,&output,&errs)) {
        delete reader;
        return true;
    }

    delete reader;
    return false;
}

void JsonBuffer::addJsonBuffer(const char *pData, int iLength)
{
    m_bufferLock.Acquire();
    if (pData != 0 && iLength > 0) {
      m_szBuffer.append(pData, iLength);
    }

    m_bufferLock.Release();
}

void JsonBuffer::addJsonBuffer(const std::string &pStr)
{
    m_bufferLock.Acquire();
    m_szBuffer.append(pStr);
//    std::string decrypt =
//            utils::DecryptString(m_szBuffer);
    m_bufferLock.Release();
}

void JsonBuffer::clearJsonBuffer()
{
    m_bufferLock.Acquire();
    m_szBuffer.clear();
    m_iStartPos = 0;
    while(!m_cFlag.empty())
        m_cFlag.pop();
    m_bufferLock.Release();
}

bool JsonBuffer::parseJson(std::string &jsonBuffer)
{
    const char *pStr = m_szBuffer.c_str();
    int   length = m_szBuffer.length();
    int i = m_iStartPos;

    for (;i < length;i++) {
        char c = pStr[i];

        switch(c)
        {
        case '{':
            if (!m_cFlag.empty()) {
                char top = m_cFlag.top();
                if (top == '"')
                    break;
            }
            m_cFlag.push('{');
            break;
        case '}':
            if (!m_cFlag.empty()) {
                char top = m_cFlag.top();
                if (top == '"')
                    break;
                else if (top == '[') {
                    //删去不合法
                    clearErrBuffer(i);
                    return false;
                }
                else if (top == '{') {
                    m_cFlag.pop();
                    if (m_cFlag.empty()) {
                        tripJsonBuffer(i,jsonBuffer);
                        return true;
                    }
                }
            }
            else {
                //删去不合法
                clearErrBuffer(i);
                return false;
            }
            break;
        case '[':
            if (!m_cFlag.empty()) {
                char top = m_cFlag.top();
                if (top == '"')
                    break;
            }
            m_cFlag.push('[');
            break;
        case ']':
            if (!m_cFlag.empty()) {
                char top = m_cFlag.top();
                if (top == '"')
                    break;
                else if (top == '{') {
                    //删去不合法
                    clearErrBuffer(i);
                    return false;
                }
                else if (top == '[') {
                    m_cFlag.pop();
                    if (m_cFlag.empty()) {
                        tripJsonBuffer(i,jsonBuffer);
                        return true;
                    }
                }
            }
            else {
                //删去不合法
                clearErrBuffer(i);
                return false;
            }
            break;
        case '"':
            if (!m_cFlag.empty()) {
                char top = m_cFlag.top();
                if (top == '"') {
                    m_cFlag.pop();
                    break;
                }
            }
            m_cFlag.push('"');
            break;
        case '\\':
            ++i;
            break;
        default:
            break;
        }
    }
    m_iStartPos = i;
    return false;
}

void JsonBuffer::clearErrBuffer(int pos)
{
    while(!m_cFlag.empty())
        m_cFlag.pop();

    m_szBuffer.erase(0,pos+1);

    m_iStartPos = 0;
}

void JsonBuffer::tripJsonBuffer(int pos, std::string &jsonBuffer)
{
    jsonBuffer = m_szBuffer.substr(0,pos+1);
    m_szBuffer.erase(0,pos+1);
    m_iStartPos = 0;
    int index = jsonBuffer.find_first_of("{[");
    if (index > 0) {
        jsonBuffer.erase(0,index);
    }
}
